package demo.security;

import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionMessage;
import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.AccessTokenConverter;
import org.springframework.security.oauth2.provider.token.DefaultAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;


@Configuration
@Conditional(DemoMemoryTokenStoreCondition.class)
public class InMemoryConfiguration {
	Logger logger = LoggerFactory.getLogger(getClass());
		
	@Bean("MyTokenStore")	
	public TokenStore tokenStore() {
		return new InMemoryTokenStore();
	}
	
	@Bean("MyAccessTokenConverter")
	public AccessTokenConverter accessTokenConverter() {
		return new DefaultAccessTokenConverter();
	}
	
	@Bean("MyTokenEnhancer")
	public TokenEnhancer tokenEnhancer() {
	    return new TokenEnhancer(){
			@Override
			public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {				
				logger.debug("*********TokenEnhancer:enhance accessToken:{}",accessToken);
				
				Map<String, Object> customInfo = new HashMap();
				customInfo.put("organization", "demo-abc");
				customInfo.put("principal", authentication.getPrincipal());
				((DefaultOAuth2AccessToken)accessToken).setAdditionalInformation(customInfo);
				return accessToken;
			}		
		};
	}
}

class DemoMemoryTokenStoreCondition extends SpringBootCondition{

	@Override
	public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {

		ConditionMessage.Builder message = ConditionMessage.forCondition("demo.tokenStore Condition");
		
		String tokenStore = context.getEnvironment().getProperty("demo.tokenStore");
		if("MEMORY".equals(tokenStore)) {
			return ConditionOutcome.match(message.foundExactly("Memory tokenStore"));
		}
		return ConditionOutcome.noMatch(message.didNotFind("Memory tokenStore").atAll());
	}
	
}
